var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var XBRLCore = (function () {
    function XBRLCore(el, cssPath) {
        this.el = el;
        this.cssPath = cssPath;
        this.xbrl = "";
        this.hook = { openHook: [], childHook: [], closeHook: [] };
        this.hookDom = { openHook: [], childHook: [], closeHook: [] };
        this.$window = null;
        this.$document = null;
        this.LT = "&lt;";
        this.GT = "&gt;";
        this.SP = "&nbsp;";
        this.el.setAttribute("allowFullscreen", "true");
        this.$window = this.el.contentWindow;
        this.$document = this.el.contentDocument;
    }
    XBRLCore.prototype.$ = function (selector) { return this.$document.querySelectorAll(selector); };
    XBRLCore.prototype.$$ = function (selector) { return Array.prototype.slice.call(this.$(selector)); };
    XBRLCore.prototype.matches = function (el, selector) {
        if (!selector || !el || el.nodeType !== 1)
            return false;
        var _matches = (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector);
        return _matches.call(el, selector);
    };
    XBRLCore.prototype.animate = function (config, action) {
        var win = this.$window, scrope = this;
        var opt = { from: 0, to: 0, delay: 0, duration: 1, timingFunction: 'linear' };
        for (var p in config)
            opt[p] = config[p];
        if (opt.from == opt.to)
            return;
        var begin = +new Date() + opt.delay * 1000, end = begin + opt.duration * 1000, last = +new Date();
        var tick = function () {
            if (last >= begin && last <= end) {
                var v = (function (start, alter, curTime, dur) {
                    var progress = curTime / dur * 2;
                    return (progress < 1 ? Math.pow(progress, 2) : -((--progress) * (progress - 2) - 1)) * alter / 2 + start;
                })(opt.from, opt.to - opt.from, last - begin, end - begin);
                action(v);
            }
            if (last > end) {
                action(opt.to);
                return;
            }
            last = +new Date();
            win.requestAnimationFrame(tick);
        };
        tick();
    };
    XBRLCore.prototype.load = function (ajaxParameters) {
        var scrope = this;
        asyncRequest(ajaxParameters, function (xbrl) {
            scrope.render(xbrl.response);
        }, this, function (xhr) {
            this.onError && this.onError("\u8BF7\u6C42\u6570\u636E\u9519\u8BEF\uFF1A" + xhr.statusText);
        });
    };
    XBRLCore.prototype.render = function (xbrl) {
        this.xbrl = xbrl;
        try {
            var parser = new DOMParser();
            var root = parser.parseFromString(this.xbrl, "application/xml");
            root.children;
            if (!root.children) {
                Object.defineProperty(XMLDocument.prototype, "children", {
                    get: function () {
                        var nodes = Array.prototype.slice.call(this.childNodes);
                        return nodes.filter(function (n) { return n.nodeType == 1; });
                    }
                });
                Object.defineProperty(Element.prototype, "children", {
                    get: function () {
                        var nodes = Array.prototype.slice.call(this.childNodes);
                        return nodes.filter(function (n) { return n.nodeType == 1; });
                    }
                });
            }
            importCss(this.$document, this.cssPath);
            console.time("1");
            this.xbrlHtml = this.renderElement(root.children[0]);
            this.$document.body.innerHTML = this.xbrlHtml;
            console.timeEnd("1");
        }
        catch (e) {
            console.log("xbrl parse error\uFF1A" + this.xbrl);
        }
    };
    XBRLCore.prototype.renderElement = function (el) {
        return this.runHook(this.hook.openHook, el) +
            this.runHook(this.hook.childHook, el) +
            this.runHook(this.hook.closeHook, el);
    };
    XBRLCore.prototype.runHook = function (hook, el) {
        var scope = this, str = "";
        return hook.reduce(function (p, c) {
            return c.call(scope, el, p);
        }, "");
    };
    XBRLCore.prototype.createDom = function (config) {
        var el = document.createElement(config.tag);
        el.className = (config.clsName || "");
        el.innerText = config.text;
        return el;
    };
    XBRLCore.prototype.renderElementbyDom = function (el) {
        var blockEl = this.createDom({ tag: "div", clsName: "xmlBlock", text: "" });
        this.runHookbyDom(this.hookDom.openHook, el, blockEl);
        this.runHookbyDom(this.hookDom.childHook, el, blockEl);
        this.runHookbyDom(this.hookDom.closeHook, el, blockEl);
        return blockEl;
    };
    XBRLCore.prototype.runHookbyDom = function (hook, el, blockEl) {
        var scope = this;
        hook.forEach(function (h) {
            blockEl = h.call(scope, el, blockEl);
        });
        return blockEl;
    };
    XBRLCore.prototype.on = function (eventName, handler) {
        this.$document.addEventListener(eventName, handler, false);
    };
    XBRLCore.prototype.off = function (eventName, handler) {
        this.$document.removeEventListener(eventName, handler, false);
    };
    XBRLCore.prototype.bindEventOnClsName = function (eventName, listenCls) {
        var doc = this.$document;
        doc.addEventListener(eventName, function (event) {
            var target = event.target;
            while (target != doc.body) {
                for (var i = 0; i < listenCls.length; i++) {
                    if (target.classList && target.classList.contains(listenCls[i])) {
                        var bubble = true, ev = null;
                        try {
                            ev = new CustomEvent(listenCls[i] + eventName, {
                                detail: target, bubbles: false, cancelable: true
                            });
                        }
                        catch (ex) {
                            ev = document.createEvent('CustomEvent');
                            ev.initCustomEvent(listenCls[i] + eventName, true, true, target);
                        }
                        ev && (bubble = doc.dispatchEvent(ev));
                        if (!bubble)
                            return;
                    }
                }
                target = target.parentElement;
            }
        }, false);
    };
    return XBRLCore;
}());
var XBRLViewer = (function (_super) {
    __extends(XBRLViewer, _super);
    function XBRLViewer(el, cssPath) {
        var _this = _super.call(this, el, cssPath) || this;
        _this.el = el;
        _this.cssPath = cssPath;
        _this.$lastSelected = [];
        _this.hook.openHook.push(_this.hOpen);
        _this.hook.childHook.push(_this.hChild);
        _this.hook.closeHook.push(_this.hClose);
        _this.hookDom.openHook.push(_this.hOpenbyDom);
        _this.hookDom.childHook.push(_this.hChildbyDom);
        _this.hookDom.closeHook.push(_this.hClosebyDom);
        _this.bindEventOnClsName("click", ["xmlBlock", "attr", "nodeName", "textValue", "plus"]);
        _this.on("plusclick", _this.fPlusClick);
        return _this;
    }
    XBRLViewer.prototype.hOpen = function (el, str) {
        var str = "<div class=\"xmlBlock\">";
        el.children.length && (str += "<span class=\"plus\"></span><span class=\"mark\"></span>");
        str += "<span class=\"nodeName\">" + this.LT + el.nodeName + "</span>";
        if (el.attributes.length) {
            for (var i = 0; i < el.attributes.length; i++) {
                var attr = el.attributes[i];
                str += "<span class=\"attr\">" + this.SP + "\n                            <span class=\"attrName\">" + attr.nodeName + "</span>\n                            <span class=\"attrValue\">\"" + attr.nodeValue + "</span>\"\n                        </span>";
            }
        }
        return str;
    };
    XBRLViewer.prototype.hChild = function (el, str) {
        var str = "<span class=\"nodeName\">" + this.GT + "</span>";
        if (!el.children.length) {
            if (el.textContent == "") {
                str = "";
            }
            else {
                str += "<span class=\"textValue\">" + el.textContent + "</span>";
            }
        }
        else {
            for (var i = 0; i < el.children.length; i++) {
                str += this.renderElement(el.children[i]);
            }
        }
        return str;
    };
    XBRLViewer.prototype.hClose = function (el, str) {
        var len = el.childNodes.length;
        if (!len)
            return "<span class=\"nodeName\">" + this.SP + "/" + this.GT + "</span></div>";
        else
            return "<span class=\"nodeName\">" + this.LT + "/" + el.nodeName + this.GT + "</span></div>";
    };
    XBRLViewer.prototype.hOpenbyDom = function (el, blockEl) {
        el.children.length && blockEl.appendChild(this.createDom({ tag: 'span', clsName: "plus", text: "" }));
        blockEl.appendChild(this.createDom({ tag: "span", clsName: "nodeName", text: "<" + el.nodeName }));
        if (el.attributes.length) {
            for (var i = 0; i < el.attributes.length; i++) {
                var attr = el.attributes[i];
                var attrDom = this.createDom({ tag: "span", clsName: "attr", text: "" });
                attrDom.appendChild(this.createDom({ tag: "span", clsName: "attrName", text: attr.nodeName }));
                attrDom.appendChild(this.createDom({ tag: "span", clsName: "attrValue", text: "\"" + attr.nodeValue + "\"" }));
                blockEl.appendChild(attrDom);
            }
        }
    };
    XBRLViewer.prototype.hChildbyDom = function (el, blockEl) {
        var gtTag = this.createDom({ tag: "span", clsName: "nodeName", text: ">" });
        if (!el.children.length) {
            if (el.textContent !== "") {
                blockEl.appendChild(gtTag);
                blockEl.appendChild(this.createDom({ tag: "span", clsName: "textValue", text: el.textContent }));
            }
        }
        else {
            blockEl.appendChild(gtTag);
            for (var i = 0; i < el.children.length; i++) {
                blockEl.appendChild(this.renderElementbyDom(el.children[i]));
            }
        }
    };
    XBRLViewer.prototype.hClosebyDom = function (el, blockEl) {
        var len = el.childNodes.length;
        if (!len)
            blockEl.appendChild(this.createDom({ tag: "span", clsName: "nodeName", text: "/>" }));
        else
            blockEl.appendChild(this.createDom({ tag: "span", clsName: "nodeName", text: "</" + el.nodeName + ">" }));
    };
    XBRLViewer.prototype.fPlusClick = function (ev) {
        var plus = ev.detail;
        plus.parentElement.classList.toggle("fold");
    };
    return XBRLViewer;
}(XBRLCore));
var XBRLEditer = (function (_super) {
    __extends(XBRLEditer, _super);
    function XBRLEditer(el, cssPath) {
        var _this = _super.call(this, el, cssPath) || this;
        _this.el = el;
        _this.cssPath = cssPath;
        _this.hook.openHook.push(_this.hOpenDelPlus);
        _this.hook.childHook.push(_this.hChildWithEditor);
        _this.off("plusclick", _this.fPlusClick);
        return _this;
    }
    XBRLEditer.prototype.hOpenDelPlus = function (el, str) {
        el.children.length && (str = str.replace("<span class=\"plus\"></span>", ""));
        return str;
    };
    XBRLEditer.prototype.hChildWithEditor = function (el, str) {
        if (!el.children.length && el.textContent != "") {
            return str.replace(/<span class="textValue">(.*?)<\/span>/g, function (a, b) {
                return "<span class=\"textValue\"><input type=\"text\" value=\"" + b + "\" /></span>";
            });
        }
        else {
            return str;
        }
    };
    return XBRLEditer;
}(XBRLViewer));
